package com.minimvc.core
{
	import com.minimvc.interfaces.ICommand;
	import com.minimvc.interfaces.IController;
	import com.minimvc.interfaces.IReusable;
	import com.minimvc.interfaces.IView;
	
	import flash.events.Event;
	import flash.utils.Dictionary;
	
	/**
	 *  事件命令注册管理器
	 * @author crl
	 * 
	 */	
	[ExcludeClass]
	public class Controller implements IController
	{
		protected const SINGLETON_MSG : String = "Controller Singleton already constructed!";
		private const HAS_COMMAND_MSG:String="已经存在了此事件的command类型";
		protected var view : IView;
		protected var commandMap :Dictionary;
		
		/**
		 * 复用列表; 
		 */		
		protected var reusableMap:Dictionary;
		public function Controller( )
		{
			if (instance != null) throw Error(SINGLETON_MSG);
			instance = this;
			commandMap = new Dictionary();	
			reusableMap=new Dictionary();
			initializeController();	
			
		}
		
		protected function initializeController(  ) : void 
		{
			view = View.getInstance();
		}
		
		protected static var instance : IController;
		public static function getInstance() : IController
		{
			if ( instance == null ) instance = new Controller( );
			return instance;
		}
		
		public function execute( event :Event ) : void
		{
			var commandInstance : ICommand= reusableMap[event.type];
			if(commandInstance != null){
				commandInstance.execute( event );
				return;
			}
			var commandClassRef : Class =commandMap[ event.type];
			if ( commandClassRef == null ) return;
			
			commandInstance = new commandClassRef();
			commandInstance.execute( event );
			if(commandInstance is IReusable){
				if((commandInstance as IReusable).isReusable)reusableMap[event.type]=commandInstance;
			}
		}
		
		public function registerCommand( eventType : String, commandClassRef : Class ) : void
		{
			if ( hasCommand( eventType ) ) {
				throw new Error(HAS_COMMAND_MSG);
			}
			
			view.addEventListener( eventType,execute);
			commandMap[ eventType ] = commandClassRef;
		}
		
		public function hasCommand( eventType:String ) : Boolean
		{
			return commandMap[ eventType ] != null;
		}
		
		public function removeCommand( eventType : String ) : void
		{
			if ( hasCommand( eventType ) ==false)
			{
				return;
			}
			if( eventType in reusableMap ){
				reusableMap[eventType] = null;
				delete reusableMap[eventType];
			}
			view.removeEventListener(eventType, execute);
			
			commandMap[ eventType ] = null;
			delete commandMap[ eventType ];
			
		}
	}
}